package top.eggcode.plugins.query;

import top.eggcode.common.error.ApplicationException;
import top.eggcode.common.lang.BeanUnit;
import top.eggcode.plugins.query.util.CaseFormat;

import java.beans.IntrospectionException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.math.BigInteger;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 行记录转换器
 * Title: 行数据转换器
 * Description: TODO
 * Date: 2021/9/12 23:46
 *
 * @author JiaQi Ding
 * @version 1.0
 */
public class RowTransformer {

    public static <T> List<T> toBeanList(List<Map<String, Object>> rowList, Class<T> beanType) {
        List<T> models = new LinkedList<>();
        if (rowList.size() > 0) {
            Map<String, String> fieldNameMap = new HashMap<>(10);
            rowList.get(0).keySet().forEach(name -> fieldNameMap.put(name, CaseFormat.toCamel(name)));
            for (Map<String, Object> row : rowList) {
                T model;
                try {
                    model = beanType.getDeclaredConstructor().newInstance();
                } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                    e.printStackTrace();
                    throw new ApplicationException(e, "对象创建失败");
                }
                Set<String> columns = row.keySet();
                for (String name : columns) {
                    Object value = row.get(name);
                    String beanFieldName = fieldNameMap.get(name);
                    Object originalValue;
                    // 值为空的不处理；
                    if (value == null) {
                        continue;
                    }
                    try {
                        Field beanField;
                        try {
                            // 尝试从自己身上获取字段
                            beanField = beanType.getDeclaredField(beanFieldName);
                        } catch (NoSuchFieldException e) {
                            // 从父类对象获取
                            // 实体最多只能有一个父类
                            beanField = beanType.getSuperclass().getDeclaredField(beanFieldName);
                        }
                        Class<?> fieldType = beanField.getType();

                        if (fieldType == LocalDateTime.class) {
                            originalValue = ((Timestamp) value).toLocalDateTime();
                            // tinyint -》 boolean
                        } else if (fieldType == Boolean.class && value.getClass() == Byte.class) {
                            int intValue = (Byte) value & 0xff;
                            if (intValue <= 0) {
                                originalValue = false;
                            } else {
                                originalValue = true;
                            }
                        } else if (value.getClass() == Boolean.class) {
                            originalValue = value;
                        } else if (fieldType == Long.class) {
                            originalValue = ((BigInteger) value).longValue();
                        } else {
                            originalValue = value;
                        }

                        BeanUnit.setAttributeValue(beanFieldName, originalValue, model);
                    } catch (NoSuchFieldException | IntrospectionException | InvocationTargetException | IllegalAccessException e) {
                        e.printStackTrace();
                        throw new ApplicationException(e, beanFieldName + " 无法获取字段");
                    }
                }
                models.add(model);
            }
        }
        return models;
    }


}
